﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using DCS.Business.Manager;
using DCS.DataProvider;
using DCS.Business.Model;
using DCS.Business.Interface;
//using MessagerSync.ESBTMPPService;
using System.IO;

namespace MessagerSync
{
    public abstract class SyncerBase : IMessageSyncer
    {
        #region Fields
        protected static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        static string MessageType = ConfigurationManager.AppSettings["MessageType"];
        static int BatchSize = Convert.ToInt32(ConfigurationManager.AppSettings["BatchSize"]);
        static bool esbHeaderBit = false;
        static DCSFileManager dcsManager;
        static PublishManager pubManager;

        #endregion

        #region IMessageSyncer Members

        public void Init()
        {
            IUnityContainer myContainer = new UnityContainer();
            UnityConfigurationSection section
              = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            section.Containers["Data"].Configure(myContainer);

            IDataProvider dp = myContainer.Resolve<IDataProvider>();

            dcsManager = new DCSFileManager(dp);
            pubManager = new PublishManager(dp);
        }

        public void DetectAndSync()
        {
            List<DCSFileGroup> dcsFileGroups;
            MessageGroup messageList;

            List<DCSFileGroup> dcsFailedFileGroups;

            List<DCSFileGroup> dcsAllFileGroups;

            try
            {
                dcsAllFileGroups = pubManager.GetSyncMessagesByMessageType(out messageList, MessageType, BatchSize);
            }
            catch (Exception ex)
            {
                Logger.Fatal(ex);
                return;
            }

            dcsFailedFileGroups = dcsAllFileGroups.Where(g => (g.First().Status & FileStatus.FinishParse) == 0).ToList();
            dcsFileGroups = dcsAllFileGroups.Where(g => (g.First().Status & FileStatus.FinishParse) == FileStatus.FinishParse).ToList();

            #region DCSFile Sync

            SyncAndUpdateDCSFiles(dcsFileGroups, messageList, FileStatus.ECIFSyncOK);

            SyncAndUpdateDCSFiles(dcsFailedFileGroups, messageList, FileStatus.ECIFSyncFail);

            #endregion
        }

        #endregion

        #region abstract function
        public abstract void CallESBWS(object esbparam, SoapHeadInfo esbheader);


        public abstract object GetESBParam(DCSFileGroup group, MessageGroup messagerList, bool flightOnly);
        #endregion

        #region private function

        private void SyncAndUpdateDCSFiles(List<DCSFileGroup> dcsFileGroups, MessageGroup messageList,FileStatus status)
        {
            List<DCSFile> syncedFileList = new List<DCSFile>();

            List<ESBSyncLog> logList = new List<ESBSyncLog>();

            foreach (DCSFileGroup group in dcsFileGroups)
            {
                try
                {


                    object esbparam = GetESBParam(group, messageList, false);

                    SoapHeadInfo esbheader = GetESBHeader(status==FileStatus.ECIFSyncOK?ECIFSyncStatus.Success:ECIFSyncStatus.Failed);
                   // Logger.WarnFormat("{2}-{0}-{1}", group.GroupName, esbheader.ServiceSn, status);
                    CallESBWS(esbparam, esbheader);
                    group.ForEach(d => d.Status = status);
                    syncedFileList.AddRange(group);

                    ESBSyncLog log = new ESBSyncLog();
                    log.ServiceSn = esbheader.ServiceSn;
                    log.DCSGroupName = group.GroupName;
                    log.MessageType = MessageType;
                    log.ESBSyncTime = DateTime.Now;
                    log.ESBSyncStatus = (int)status;

                    logList.Add(log);
                   
                }
                catch (System.Web.Services.Protocols.SoapException soex)
                {
                    Logger.Error("Soap Error webservice - " + group.GroupName + "\r\n" + soex.Detail.InnerXml, soex);
                    //syncedFileList.AddRange(group);
                }
                catch (Exception ex)
                {
                    Logger.Fatal("Error call webservice - " + group.GroupName, ex);
                    //syncedFileList.AddRange(group);
                }
            }
            dcsManager.UpdateDCSFilesStatus(syncedFileList);
            Logger.InfoFormat("{0} {1} files Sync Success.", syncedFileList.Count, MessageType);

            //记录同步日志
            try
            {
                if (logList.Count > 0)
                {
                    pubManager.InsertLogList(logList);
                }
            }
            catch (Exception e)
            {
                Logger.Error("Error on insert Sync Log", e);
            }
        }


        private static SoapHeadInfo GetESBHeader(ECIFSyncStatus sendStatus)
        {
            SoapHeadInfo headinfo = new SoapHeadInfo();
            headinfo.ChannelId = "01";
            headinfo.CompressionFlag = " ";
            headinfo.EncryptionFlag = " ";
            headinfo.LogPayloadFlag = "N";
            headinfo.NeedRequest = " ";
            headinfo.ProcessTimestamp = DateTime.Now.ToString("yyyyMMddhhmmssfff");
            headinfo.RequesterId = "0018";
            if (MessageType == "PFS")
            {
                headinfo.ServiceId = "00000000000002";
                headinfo.ServiceSn = "100180020" + DateTime.Now.ToString("yyyyMMddhhmmssfff") + (esbHeaderBit ? "01" : "02");
            }
            else if (MessageType == "PRL")
            {
                headinfo.ServiceId = "00000000000001"; ;
                headinfo.ServiceSn = "100180010" + DateTime.Now.ToString("yyyyMMddhhmmssfff") + (esbHeaderBit ? "01" : "02");
            }
                headinfo.Status = sendStatus == ECIFSyncStatus.Success ? "S" : "F";
            headinfo.SystemId = "0018";
            headinfo.TimeOut = " ";
            headinfo.UserId = " ";
            headinfo.Password = " ";
            headinfo.VersionId = "01";
            esbHeaderBit = !esbHeaderBit;
            return headinfo;
        }
        #endregion
    }


}
